package com.isoftstone.disk.service.impl;

import com.isoftstone.disk.entity.FileObsEntity;
import com.isoftstone.disk.entity.RenameFileEntity;
import com.isoftstone.disk.service.DiskService;
import com.isoftstone.platform.common.uitl.DateUtil;
import com.isoftstone.platform.common.uitl.FileUtil;
import com.isoftstone.platform.entity.PadingRstType;
import com.obs.services.ObsClient;
import com.obs.services.model.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.io.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service("diskService")
public class DiskServiceImpl implements DiskService {
    @Value("${end.point}")
    private String endPoint = "";
    @Value("${ak}")
    private String ak = "";
    @Value("${sk}")
    private String sk = "";
    @Value("${backet.name}")
    private String backetName = "";
    private static ObsClient obsClient = null;

    private synchronized ObsClient getSigleInstance(){
        if(obsClient == null){
            obsClient = new ObsClient(ak,sk,endPoint);
        }
        return obsClient;
    }
    @Override
    public void addFile(String fileNameDesc, String fileName, InputStream inputStream) {
        ObsClient obsClient = getSigleInstance();
        obsClient.putObject(backetName,fileName,inputStream);
    }


    @Override
    public PadingRstType<FileObsEntity> getFileInfolist() {
        ObsClient obsClient = getSigleInstance();
        ObjectListing objectListing = obsClient.listObjects(backetName);
        List<ObsObject> obsObjects = objectListing.getObjects();

        PadingRstType<FileObsEntity> padingRstType = new PadingRstType<FileObsEntity>();
        FileObsEntity fileObsEntity;
        List<FileObsEntity> list = new ArrayList<>();
        for(ObsObject obsObject: obsObjects){
            fileObsEntity = new FileObsEntity();
            list.add(fileObsEntity);
            fileObsEntity.setObjectKey(obsObject.getObjectKey());
            fileObsEntity.setContentLength(FileUtil.clcltn(obsObject.getMetadata().getContentLength()/1024f));
            fileObsEntity.setLastModified(DateUtil.formatDate(obsObject.getMetadata().getLastModified()));
            //list.add(fileObsEntity);
        }
        padingRstType.setTotal(obsObjects.size());
        padingRstType.setRawRecords(list);
        padingRstType.putItems();
        return padingRstType;
    }

     @Override
     public ResponseEntity<byte[]> download(String fileId) {
         ObsClient obsClient = getSigleInstance();
         ObsObject obsObject = obsClient.getObject(backetName, fileId);
         try(ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();){
             InputStream inputStream = obsObject.getObjectContent();
             byte[] block = new byte[1024];
             int lengh = 0;
             while((lengh = inputStream.read(block))> 0){
                 byteOutputStream.write(block,0,lengh);
                 byteOutputStream.flush();
             }
             HttpHeaders headers =
                     new HttpHeaders();
             headers.setContentDispositionFormData("attachment",fileId);//告知浏览器以下载方式打开
             headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);//设置MIME类型
             return new ResponseEntity<byte[]>(
                                         byteOutputStream.toByteArray(),
                                         headers,
                                         HttpStatus.CREATED);
         }catch (IOException e){
             e.printStackTrace();
         }
         return null;
     }

     @Override
     public void delete(String fileId){
         ObsClient obsClient = getSigleInstance();
         obsClient.deleteObject(backetName, fileId);
     }

    @Override
    public void copy(String fileId)
    {
        ObsClient obsClient = getSigleInstance();
        String destobjectname=getdestobjectname(fileId);
        CopyObjectResult result = obsClient.copyObject(backetName, fileId,
                backetName, destobjectname);
        System.out.println("\t" + result.getEtag());
    }

    public String getdestobjectname(String fileId)
    {
        int point_index=fileId.lastIndexOf('.');
        String destobjectname=fileId.substring(0,point_index);

        int num=2;//复制重复文件时加的后缀
        int search_type=1;//搜索方式
        int not_ectype=1;//判断有没有副本
        ObsClient obsClient = getSigleInstance();
        ObjectListing listobject=obsClient.listObjects(backetName);
        for(ObsObject obsObject : listobject.getObjects())
        {
            if(obsObject.getObjectKey().indexOf(destobjectname+"-副本("+num+")")!=-1)
            {
                search_type=2;
                not_ectype=0;
                num++;
                continue;
            }
            if(obsObject.getObjectKey().indexOf(destobjectname+"-副本")!=-1)
            {
                search_type=2;
                not_ectype=0;
            }
            if(search_type==2)
            {
                if(obsObject.getObjectKey().indexOf(destobjectname+"-副本(")!=-1)
                {
                    continue;
                }
                else if(obsObject.getObjectKey().equals(destobjectname+"-副本"+fileId.substring(point_index,fileId.length())))
                {
                    break;
                }
                else
                {
                    num=1;
                    break;
                }
            }
        }

        if(not_ectype==1||num==1)
        {
            destobjectname=destobjectname+"-副本"+fileId.substring(point_index,fileId.length());
        }
        else
        {
            destobjectname=destobjectname+"-副本("+num+")"+fileId.substring(point_index,fileId.length());
        }
        return destobjectname;
    }

    //[Liu]预览服务
    @Override
    public String preview(String fileId) {
        System.out.println("[Liu Debug]执行预览操作~Now Preview Service:(preview)");
        String resultUrl;
        String objectKey = fileId;
        TemporarySignatureRequest request = new TemporarySignatureRequest();
        request.setBucketName(backetName);
        request.setObjectKey(objectKey);
        request.setRequestDate(new Date());
        //1分钟后链接失效
        request.setExpires(60*60*5);
        TemporarySignatureResponse signature = obsClient.createTemporarySignature(request);
        resultUrl = signature.getSignedUrl();
        System.out.println("[Liu Debug]获取临时URL~Get Temp Url:(preview):转码前url="+resultUrl);

        //[Liu]这里有个贼蠢的问题，如果不转码，&符号不会变成%26，带有作为外链打开时会被浏览器舍弃&后的数据（可能），然后Word就没法预览
        //[Liu]但是,如果转成UTF8，在前端直接通过标签预览图片和MP3之类的时候，作为标签的src属性，他又没法识别，我人都麻了
        //[Liu]最后在前端分情况解决
        /*
        try {
            resultUrl=URLEncoder.encode(resultUrl, "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        System.out.println("[Liu Debug]获取临时URL~Get Temp Url:(preview):转码UTF8后url="+resultUrl);*/
        return resultUrl;
    }

    @Override
    public void addFloder(String floderName){
        // 创建ObsClient实例
        ObsClient obsClient1 = new ObsClient(ak, sk, endPoint);
        final String KeySuffixWithSlash  = floderName;
        System.out.println(KeySuffixWithSlash);
        obsClient1.putObject(backetName, KeySuffixWithSlash+ "/", new ByteArrayInputStream(new byte[0]));
//// 在文件夹下创建对象
        //obsClient.putObject(backetName,KeySuffixWithSlash + "/" + floderFileName,new ByteArrayInputStream("Hello OBS".getBytes()));

    }

    @Override
    public String share(String fileId) {
        TemporarySignatureRequest request = new TemporarySignatureRequest();
        request.setBucketName(backetName);
        request.setObjectKey(fileId);
        request.setRequestDate(new Date());
        // 1小时后链接失效
        request.setExpires(60*60);
        TemporarySignatureResponse signature = obsClient.createTemporarySignature(request);
        return signature.getSignedUrl();
    }

    @Override
    public void moveFile(String floderName,String floderFileName){
        // 创建ObsClient实例
        ObsClient obsClient1 = new ObsClient(ak, sk, endPoint);
        final String KeySuffixWithSlash  = floderName;
        System.out.println(KeySuffixWithSlash);
        obsClient1.putObject(backetName, KeySuffixWithSlash+ "/", new ByteArrayInputStream(new byte[0]));
//// 在文件夹下创建对象
        obsClient.putObject(backetName,KeySuffixWithSlash + "/" + floderFileName,new ByteArrayInputStream("Hello OBS".getBytes()));
        //删除对象
        obsClient.deleteObject(backetName, floderFileName);
    }

    @Override
    public void updateFile(RenameFileEntity fileObsEntity) {
        ObsClient obsClient = getSigleInstance();
        ObsObject obsObject = obsClient.getObject(backetName,fileObsEntity.getOldFileName());
        obsClient.putObject(backetName, fileObsEntity.getNewFileName(), obsObject.getObjectContent());
        obsClient.deleteObject(backetName,fileObsEntity.getOldFileName());
    }

}
